页脚组件设计思路
首页底部的 Footer 组件是纯 HTML + CSS 的布局练习,不涉及复杂 JS 逻辑。无论使用什么框架或 UI 库,核心能力仍然是 HTML/CSS 布局——框架和工具只是简化这个过程。
Footer 的结构分为四个区域:
┌─────────────────────────────────┐
│ 导航菜单 │ ← 产品 | 社区 | 学习 | 关于
├─────────────────────────────────┤
│ 联系信息 │ 外链信息 │ ← 图标 + 文字列表
│ 邮箱/电话 │ 博客/官网 │
├─────────────────────────────────┤
│ 社交媒体图标 │ ← 微信 / 微博(hover 显示二维码)
├─────────────────────────────────┤
│ © 2026 toimc | ICP备案 │ ← 版权信息
└─────────────────────────────────┘
text
组件实现
基本结构
<!-- components/DefaultFooter.vue -->
<template>
<div class="bg-gray-800 text-gray-300 text-sm py-8">
<div class="container mx-auto max-w-1200px">
<!-- 导航菜单 -->
<nav class="flex justify-between items-center w-full mb-4">
<ul class="flex justify-start w-full">
<li v-for="item in menuItems" :key="item.label" class="px-4 text-gray-400">
<a :href="item.link">{{ item.label }}</a>
</li>
</ul>
<!-- 社交媒体图标 -->
<div class="flex gap-4 text-lg cursor-pointer pr-4">
<div class="group relative">
<icon-park-outline-wechat />
<img
src="@/assets/images/wechat.jpg"
class="absolute left-50% -translate-x-1/2 -translate-y-full w-20 h-20 rounded opacity-0 group-hover:opacity-100"
/>
</div>
<div class="group relative">
<icon-park-outline-weibo />
<img
src="@/assets/images/weibo.jpg"
class="absolute left-50% -translate-x-1/2 -translate-y-full w-20 h-20 rounded opacity-0 group-hover:opacity-100"
/>
</div>
</div>
</nav>
<!-- 分隔线 -->
<div class="border-b border-gray-600 w-full" />
<!-- 联系信息与外链 -->
<div class="flex mt-4 ml-4">
<div class="mr-8">
<span class="flex items-center text-gray-200 font-bold text-lg mb-2">
<icon-park-outline-phone class="mr-2" />
联系信息
</span>
<p><a href="mailto:admin@toimc.com">admin@toimc.com</a></p>
<p>400-888-8888</p>
<p>北京市朝阳区xxx</p>
</div>
<div>
<span class="flex items-center text-gray-200 font-bold text-lg mb-2">
<icon-park-outline-link class="mr-2" />
友链信息
</span>
<p><a href="https://toimc.com/blog">博客</a></p>
<p><a href="https://toimc.com">官网</a></p>
</div>
</div>
<!-- 版权信息 -->
<div class="flex justify-center items-center mt-4 w-full">
<span>Copyright © 2026 toimc</span>
<a href="https://beian.miit.gov.cn/" class="ml-2 flex items-center" target="_blank">
<img src="@/assets/icons/icon.png" class="w-5 h-5 inline-block bg-contain mr-2" />
{{ icp }}
</a>
</div>
</div>
</div>
</template>
vue
Props 定义
// defineProps
const props = defineProps({
icp: {
type: String,
default: '',
},
});
typescript
ICP 备案信息通过 Props 传入,使组件可复用。
UnoCSS 关键用法
group + hover:父元素悬停控制子元素
<div class="group relative">
<icon-park-outline-wechat />
<img class="opacity-0 group-hover:opacity-100" />
</div>
html
- 外层
group:标记为父级组 - 子层
group-hover:opacity-100:当鼠标悬停在父级时,子元素变为可见
这与 Tailwind CSS 的 group 用法完全一致。
peer:兄弟元素状态控制
<input class="peer" />
<p class="hidden peer-invalid:block text-red-500">请输入正确的邮箱</p>
html
peer:标记为参考元素peer-invalid:block:当兄弟元素(input)处于 invalid 状态时显示
注意:
peer必须写在目标元素之前,且只能控制后面的兄弟元素。
布局常用类
| 类名 | 效果 |
|---|---|
flex | 弹性布局 |
justify-between | 两端对齐 |
items-center | 垂直居中 |
gap-4 | 子元素间距 |
mx-auto | 水平居中 |
max-w-1200px | 最大宽度 |
间距选择:margin vs padding
| 属性 | 影响范围 | 适用场景 |
|---|---|---|
padding | 影响元素内部空间(含背景) | 元素内部留白 |
margin | 影响元素外部距离(不含背景) | 元素之间的间距 |
在 Layout 中使用
<!-- layouts/default.vue -->
<template>
<div>
<DefaultHeader />
<main>
<slot />
</main>
<DefaultFooter icp="京ICP备xxxxxxxx号" />
</div>
</template>
vue
Footer 放在 default layout 中,所有使用该布局的页面自动包含底部信息。
↑